// Copyright 2021 by 马万里. All rights reserved.
// 开发团队 ：   鸡中之霸
// 开发人员 ：   马万里
// 开发时间 ：   2021/3/3 14:17
// 文件名称 ：   order.go
// 工程名称 ：   seckill
// 开发工具 ：   GoLand
//

package repositories

import (
	"database/sql"
	"foreground/datamodels"
	"foreground/common"
)

type IOrderRepository interface {
    Conn() (err error)
    Insert(o *datamodels.Order) (id int64, err error)
    Delete(id int64) bool
    Update(o *datamodels.Order) (err error)
    SelectByKey(id int64) (o *datamodels.Order, err error)
    SelectAll() (ol []*datamodels.Order, err error)
    SelectAllWithInfo() (orderInfo map[int]map[string]string, err error)
}

type OrderManager struct {
    table     string
    mysqlConn *sql.DB
}

func NewOrderManager(table string, db *sql.DB) IOrderRepository {
    return &OrderManager{
        table:     table,
        mysqlConn: db,
    }
}

func (om *OrderManager) Conn() (err error) {
    if om.mysqlConn == nil {
        om.mysqlConn, err = common.NewMysqlConn()
        if err != nil {
            return err
        }
    }
    if om.table == "" {
        om.table = "order"
    }
    return
}

func (om *OrderManager) Insert(o *datamodels.Order) (id int64, err error) {
    if err = om.Conn(); err != nil {
        return
    }
    sqlStr := "INSERT `order` SET userID=?, productID=?, orderStatus=?"
    stmt, err := om.mysqlConn.Prepare(sqlStr)
    if err != nil {
        return
    }
    defer stmt.Close()
    result, err := stmt.Exec(o.UserId, o.ProductId, o.OrderStatus)
    if err != nil {
        return
    }
    return result.LastInsertId()
}

func (om *OrderManager) Delete(id int64) bool {
    if err := om.Conn(); err != nil {
        return false
    }
    sqlStr := "INSERT FROM order WHERE ID=?"
    stmt, err := om.mysqlConn.Prepare(sqlStr)
    if err != nil {
        return false
    }
    defer stmt.Close()
    _, err = stmt.Exec(id)
    if err != nil {
        return false
    }
    return true
}

func (om *OrderManager) Update(o *datamodels.Order) (err error) {
    if err = om.Conn(); err != nil {
        return err
    }
    sqlStr := "UPDATE order SET userID=?, productID=?, orderStatus=? WHERE ID=?"
    stmt, err := om.mysqlConn.Prepare(sqlStr)
    if err != nil {
        return err
    }
    _, err = stmt.Exec(o.UserId, o.ProductId, o.OrderStatus, o.ID)
    return err
}

func (om *OrderManager) SelectByKey(id int64) (o *datamodels.Order, err error) {
    if err = om.Conn(); err != nil {
        return &datamodels.Order{}, err
    }
    sqlStr := "SELECT * FROM order WHERE ID=?"
    stmt, err := om.mysqlConn.Prepare(sqlStr)
    if err != nil {
        return &datamodels.Order{}, err
    }
    row, err := stmt.Query(id)
    if err != nil {
        return &datamodels.Order{}, err
    }
    result := common.GetResultRow(row)
    if len(result) == 0 {
        return &datamodels.Order{}, err
    }
    o = new(datamodels.Order)
    common.DataToStructByTagSql(result, o)
    return
}

func (om *OrderManager) SelectAll() (ol []*datamodels.Order, err error) {
    if err = om.Conn(); err != nil {
        return nil, err
    }
    sqlStr := "SELECT * FROM order"
    stmt, err := om.mysqlConn.Prepare(sqlStr)
    if err != nil {
        return nil, err
    }
    rows, err := stmt.Query()
    if err != nil {
        return nil, err
    }
    resultRows := common.GetResultRows(rows)
    if len(resultRows) == 0 {
        return nil, err
    }
    for _, v := range resultRows {
        o := new(datamodels.Order)
        common.DataToStructByTagSql(v, o)
        ol = append(ol, o)
    }
    return
}

func (om *OrderManager) SelectAllWithInfo() (orderInfo map[int]map[string]string, err error) {
    if err = om.Conn(); err != nil {
        return nil, err
    }
    sqlStr := "SELECT o.ID, p.productName, o.orderStatus FROM order AS o LEFT JOIN product as p ON o.productID=p.ID"
    stmt, err := om.mysqlConn.Prepare(sqlStr)
    if err != nil {
        return nil, err
    }
    rows, err := stmt.Query()
    if err != nil {
        return nil, err
    }
    return common.GetResultRows(rows), err
}

